//
// Created by taojiaheng on 2020/6/4.
//

#include "Buff.h"

VariableBuff::VariableBuff(int _min_buff_size, int _max_buff_size, int _buff_cumulative_size) {
    // 变量赋值
    min_buff_size = _min_buff_size;
    max_buff_size = _max_buff_size;
    buff_cumulative_size = _buff_cumulative_size;
    // 初始化缓冲区
    buff = new char[_min_buff_size];
    bzero(buff, _min_buff_size);
    buff_size = _min_buff_size;
    buff_len = 0;
}

VariableBuff::~VariableBuff() {
    delete []buff;
}

bool VariableBuff::insetBuff(BUFF * _buff) {
    // 检查缓冲区大小是否溢出
    if((buff_len + _buff->buff_len) > max_buff_size){
        return false;
    }
    // 检查是否需要重新分配缓冲区
    if((_buff->buff_len + buff_len) > buff_size){
        // 需要重新分配 计算重新分配的大小
        int new_buff_size = buff_size + buff_cumulative_size;
        while ((_buff->buff_len + buff_len) > new_buff_size){
            new_buff_size += buff_cumulative_size;
        }
        reassignmentBuff(new_buff_size);
    }
    // 拷贝数据
    memcpy((void  *)(buff + buff_len), _buff->buff, _buff->buff_len);
    buff_len += _buff->buff_len;
    return true;
}

void VariableBuff::reassignmentBuff(int new_buff_size) {
    // 创建一块新的buff
    char * new_buff = new char[new_buff_size];
    bzero((void *)new_buff, new_buff_size);
    // 拷贝数据
    memcpy((void *)new_buff, (void *)buff, buff_len);
    delete [] buff;
    buff = new_buff;
    buff_size = new_buff_size;
}

const char *VariableBuff::data() {
    return buff;
}

int VariableBuff::length() {
    return buff_len;
}

BUFF *VariableBuff::toBuff() {
    BUFF * _buff = new BUFF ;
    _buff->buff = buff;
    _buff->buff_len = buff_len;
    return _buff;
}

void VariableBuff::clear() {
    buff_len = 0;
    bzero((void *)buff, buff_size);
}

BUFF *VariableBuff::subBuffer(int start_pos, int length) {
    // 检查是否超出范围
    if(start_pos + length > buff_len){
        return NULL;
    }
    BUFF * sub_buffer = new BUFF;
    sub_buffer->buff = new char[length];
    memcpy((void *)sub_buffer->buff, (void *)(buff + start_pos), length);
    sub_buffer->buff_len = length;
    return sub_buffer;
}

void VariableBuff::deleteBuffer(int start_pos, int length) {
    // 检查是否超出范围
    if(start_pos < 0){
        return;
    }
    if(start_pos + length > buff_len) {
        return;
    }
    memcpy(
            (void *) (buff + start_pos),
            (void *) (buff + start_pos + length),
            buff_len - (start_pos + length)
            );
    buff_len = buff_len - length;
}

bool VariableBuff::insetBuff(char * _buff) {
    BUFF temp_buffer;
    temp_buffer.buff = _buff;
    temp_buffer.buff_len = strlen(_buff);
    return insetBuff(&temp_buffer);
}

BUFF *VariableBuff::popBuff(int start_pos, int length) {
    BUFF * temp_buffer = subBuffer(start_pos, length);
    if(temp_buffer != NULL) deleteBuffer(start_pos, length);
    return temp_buffer;
}
